package com.xgk.boot.module.core.service.truck;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.cache.Cache;
import com.xgk.boot.framework.common.constant.ElmConstant;
import com.xgk.boot.framework.common.pojo.PageResult;
import com.xgk.boot.framework.common.util.cache.CacheUtils;
import com.xgk.boot.framework.common.util.file.ElmFileUtils;
import com.xgk.boot.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.xgk.boot.module.core.controller.admin.truck.vo.TruckOrderOtherReqVO;
import com.xgk.boot.module.core.dal.entity.truck.TruckOrderBolDO;
import com.xgk.boot.module.core.dal.entity.truck.TruckOrderBoxDO;
import com.xgk.boot.module.core.dal.iservice.truck.TruckOrderBolService;
import com.xgk.boot.module.core.dal.mapper.truck.TruckOrderBolMapper;
import com.xgk.boot.module.core.logistics.service.mothership.dto.OrderBolDto;
import com.xgk.boot.module.infra.framework.file.core.client.FileClient;
import com.xgk.boot.module.infra.service.file.FileServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单标签 服务实现
 */
@Service
public class TruckOrderBolServiceImpl extends ServiceImpl<TruckOrderBolMapper, TruckOrderBolDO> implements TruckOrderBolService {

    @Resource
    private FileServiceImpl fileService;

    private static final Cache<String, String> bolUpdateCache = CacheUtils.buildCache(Duration.ofHours(1));

    /**
     * todo: 保存或更新订单标签     *
     * @param orderBolDtoList 订单标签列表
     * @param orderCode       订单编码
     * @return 是否成功
     */
    @Transactional
    public boolean saveOrUpdate(List<OrderBolDto> orderBolDtoList,String orderCode) {
        // 1、检查是否存在
        LambdaQueryWrapperX<TruckOrderBolDO> eq = new LambdaQueryWrapperX<TruckOrderBolDO>().eq(TruckOrderBolDO::getOrderCode, orderCode);
        List<TruckOrderBolDO> list = this.list(eq);
        Map<String,TruckOrderBolDO> map =new HashMap<>();
        if (list != null && !list.isEmpty()) {
            // todo：存在则删除
//            this.remove(eq);
            list.forEach(item->{
                map.put(item.getType(),item);
            });
        }

        List<TruckOrderBolDO> saveBolList = new ArrayList<>();
        for (OrderBolDto orderBolDto : orderBolDtoList) {
            TruckOrderBolDO bolDO = map.get(orderBolDto.getType());
            if(bolDO!=null){
                // 存在则更新
                bolDO.setOlOriginPath(orderBolDto.getUrl())
                        .setOlOriginExpiresAt(orderBolDto.getExpiresAt());
                saveBolList.add(bolDO);
                continue;
            }
            TruckOrderBolDO truckOrderBolDO = new TruckOrderBolDO().setOrderCode(orderCode)
                    .setType(orderBolDto.getType())
                    .setOlOriginPath(orderBolDto.getUrl())
                    .setOlOriginExpiresAt(orderBolDto.getExpiresAt());
            //todo:保存对应文件，保存在本地或远端，返回真实的存储文件地址
            ElmFileUtils.FileTypeInfo fileTypeInfo = ElmFileUtils.detectFile(orderBolDto.getUrl(), orderCode, orderBolDto.getType());
            String saveFilePath = fileService.generateUploadPath(fileTypeInfo.getFileName(), ElmConstant.TRUCK_BOL);
            long fileLength = ElmFileUtils.saveFileFromUrl(orderBolDto.getUrl(), saveFilePath);
            String fileByStreamWithoutDb = fileService.createFileByStreamWithoutDb(FileUtil.getInputStream(saveFilePath), saveFilePath, ElmConstant.TRUCK_BOL, fileTypeInfo.getContentType(), fileLength);

            truckOrderBolDO.setOlPath(saveFilePath);
            truckOrderBolDO.setOlFileType(fileTypeInfo.getExtension());
            truckOrderBolDO.setOlFileLength(fileLength);
            truckOrderBolDO.setOlPathUrl(fileByStreamWithoutDb);
            FileClient masterFileClient = fileService.getMasterFileClient();
            truckOrderBolDO.setFileClientId(masterFileClient.getId());
            saveBolList.add(truckOrderBolDO);
        }
        this.saveOrUpdateBatch(saveBolList);
        return true;
    }

    public boolean ifUpdateBol(String orderCode){
        String ifPresent = bolUpdateCache.getIfPresent(orderCode);
        if(ifPresent !=null){
            return false;
        }
        bolUpdateCache.put(orderCode,"1");
        return true;
    }

    public PageResult<TruckOrderBolDO> pageTruckOrderBols(TruckOrderOtherReqVO orderOtherReqVO){
        if(orderOtherReqVO == null || StrUtil.isBlank(orderOtherReqVO.getOrderCode())){
            return new PageResult<>();
        }

        LambdaQueryWrapperX<TruckOrderBolDO> boxWrapperX = new LambdaQueryWrapperX<>();
        boxWrapperX.eq(TruckOrderBolDO::getOrderCode, orderOtherReqVO.getOrderCode());
        boxWrapperX.orderByAsc(TruckOrderBolDO::getOrderCode).orderByDesc(TruckOrderBolDO::getCreateTime);
        Page<TruckOrderBolDO> page=new Page<>(orderOtherReqVO.getCurrent(),orderOtherReqVO.getPageSize());
        Page<TruckOrderBolDO> pageRes = this.page(page, boxWrapperX);

        return new PageResult<>(pageRes.getRecords(), pageRes.getTotal(), orderOtherReqVO.getCurrent(), orderOtherReqVO.getPageSize());
    }
}
